"use strict";
let core, config, logger, _ = require('lodash'), bodyParser = require('body-parser');
let serviceName = 'api', app = require('express')(), server, event = new (require('events'))(), fs = require('fs');
let async = require('async');
let api = {
  assert: (error) => {
    if (error) {
      logger.error(error);
      throw '[' + serviceName + '] ' + error;
    }
  },
  init: (name, c) =>  new Promise((callback) => {
    serviceName = name;
    core = c;
    logger = core.getLogger(serviceName);
    config = core.getConfig(serviceName);
    let publisher = core.getService('redis').getClient();
    let subscriber = core.getService('redis').getSubscriber();
    subscriber.subscribe('commandback');
    // 监听 key 的过期事件
    subscriber.subscribe('__keyevent@0__:expired');
    subscriber.on('message', (channel, message) => {
      if (channel === 'commandback') {
        let data = JSON.parse(message);
        event.emit(data.callback, data.result);
      } else if (channel === '__keyevent@0__:expired') {
        let info = /monitor:(\w+)/.exec(message);
        if (info) {
          core.getService('sdk')
              .timeout(info[1])
              .then((response) => {
                logger.info(response)
              })
              .catch((err) => logger.error(err));
        }
      }

    });
    let funSendCommand = (command, data, callback) => {
      const callback_func = `${command}_${data.charging}_${_.now()}_${core.randomString(6)}`;
      data.code = command;
      data.callback = callback_func;
      publisher.publish('command', JSON.stringify(data));
      async.timeout((callback) => {
        event.once(callback_func, (data) => {
          callback(null, data);
        });
      }, 10000)(callback);
    }
    let port = config.port || 3000;
    let host = config.host || '127.0.0.1';
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    // 设备启动接口
    app.post('/chargings/:charging/start', function (req, res) {
      const charging = req.param('charging');
      const { balance, numbers, mobileNo, port } = req.body;
      // 设置 centerTransactionId 的值到缓存中进行数据共享 缓存时间2分钟
      publisher.setex(`centerTransactionId:${charging}-${mobileNo}`, [120, numbers], () => {
        funSendCommand('0x6c', {
          charging, balance: `${parseInt(parseFloat(balance) * 100)}`, numbers, mobileNo, port, mode: '0x20',
        }, (err, data) => {
          if (err) {
            return res.json({ err, data });
          }
          // 等待设备发送启动信号
          res.json({ err, data })
        });
      });
    });

    app.post('/chargings/:charging/book', function (req, res) {
      const charging = req.param('charging');
      const { op, minutes, port } = req.body;
      funSendCommand('0x6e', {
        charging, port, minutes, op
      }, (err, data) => {
        if (err) {
          return res.json({ err, data });
        }
        // 等待设备发送启动信号
        res.json({ err, data })
      });
    });

    app.post('/chargings/:charging/stop', function (req, res) {
      const charging = req.param('charging');
      const { port } = req.body;
      publisher.get(`stop:${charging}`, (err, value) => {
        if (value) {
          return res.json({ err, data: true })
        }
        funSendCommand('0x05', {
          charging, port, op: 'stop'
        }, (err, data) => {
          res.json({ err, data })
        });
      });
    })

    // 充电桩同步时间接口
    app.post('/chargings/:charging/systime', (req, res) => {
      const charging = req.param('charging');
      const { millisecond } = req.body;
      funSendCommand('0x42', {
        charging, millisecond
      }, (err, data) => {
        res.json({ err, data })
      });
    });

    server = app.listen(port, host, () => {
      logger.info('服务已启动, 地址: ' + host + ':' + port );
      callback();
    });
  }),
  uninit: () => {
    if (server) {
      server.close();
    }
  },
};

module.exports = api;
